package com.mzl.lal4cloud.lxw4rf.service.contract.http;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mzl.lal4cloud.lxw4rf.service.contract.bean.HeaderConfig;
import com.mzl.lal4cloud.lxw4rf.service.contract.common.Consts;
import com.mzl.lal4cloud.lxw4rf.service.contract.exception.ErrorException;
import com.mzl.lal4cloud.lxw4rf.service.contract.http.okhttp.OkHttpMediaDownloadRequestExecutor;
import com.mzl.lal4cloud.lxw4rf.service.contract.util.MD5Utils;
import com.mzl.lal4cloud.lxw4rf.service.contract.util.RSAUtils;
import okhttp3.Headers;


import java.io.File;
import java.io.IOException;

/**
 * 下载媒体文件请求执行器.
 * 请求的参数是String, 返回的结果是File
 * 视频文件不支持下载
 *
 * @author J.luo
 */
public abstract class BaseMediaDownloadRequestExecutor<H, P> implements RequestExecutor<File, String> {
    protected RequestHttp<H, P> requestHttp;
    protected File tmpDirFile;

    public BaseMediaDownloadRequestExecutor(RequestHttp<H, P> requestHttp, File tmpDirFile) {
        this.requestHttp = requestHttp;
        this.tmpDirFile = tmpDirFile;
    }

    @Override
    public void execute(String uri, String data, ResponseHandler<File> handler) throws ErrorException, IOException {
        handler.handle(this.execute(uri, data));
    }

    public static RequestExecutor<File, String> create(RequestHttp requestHttp, File tmpDirFile) {
        switch (requestHttp.getRequestType()) {
            case OK_HTTP:
                return new OkHttpMediaDownloadRequestExecutor(requestHttp, tmpDirFile);
            default:
                return null;
        }
    }

  /**
   * 获取请求头
   * @param uriWithParam
   * @param requestData
   * @return
   * @throws Exception
   */
  protected Headers getHeaders(String uriWithParam, Object requestData) throws ErrorException {
    HeaderConfig headerConfig = requestHttp.getHeaderConfig();
    Headers headers = new Headers
            .Builder()
            .add("Authorization", headerConfig.getAuthorization())
            .add("bestsign-sign-timestamp", headerConfig.getBestsignSignTimestamp().toString())
            .add("bestsign-client-id", headerConfig.getBestsignClientId())
            .add("bestsign-signature-type", "RSA256")
            .add("bestsign-signature", this.signRequest(uriWithParam, requestData, headerConfig))
            .build();
    return headers;
  }


  private String signRequest(String uriWithParam, Object requestData, HeaderConfig headerConfig) throws ErrorException {
    final ObjectMapper objectMapper = new ObjectMapper();

    try {
      String content = String.format(
              Consts.BEST_URI,
              headerConfig.getBestsignClientId(),
              headerConfig.getBestsignSignTimestamp().toString(),
              "RSA256",
              MD5Utils.stringMD5(requestData == null ? "" : objectMapper.writeValueAsString(requestData)),
              uriWithParam);

      return RSAUtils.signRSA(content, headerConfig.getPrivateKey());
    }catch (Exception e) {
      throw new ErrorException("加密错误！");
    }
  }

}
